<template>
  <div class="image-magnifier">
    <div class="image-magnifier-content">
      <div class="image-container" 
           @mousemove="handleMouseMove" 
           @mouseenter="showMagnifier" 
           @mouseleave="hideMagnifier"
           ref="imageContainer">
        <img :src="imageUrl" class="original-image" alt="示例图片">
        <div class="magnifier-lens" :style="lensStyle"></div>
      </div>
      
      <div class="magnifier-container" :class="{ active: isMagnifierVisible }">
        <img :src="imageUrl" class="magnifier-image" :style="magnifiedImageStyle" alt="放大图片">
      </div>
    </div>
    
    <div class="controls">
      <div class="control-group">
        <label for="zoom-level">放大倍数:</label>
        <input type="range" id="zoom-level" min="1.5" max="4" step="0.1" v-model="zoomLevel">
        <span>{{ zoomLevel }}x</span>
      </div>
      <div class="control-group">
        <label for="lens-size">放大镜尺寸:</label>
        <input type="range" id="lens-size" min="100" max="200" step="10" v-model="lensSize">
        <span>{{ lensSize }}px</span>
      </div>
    </div>
    
    <div class="instructions">
      <h3>使用说明</h3>
      <p>1. 将鼠标悬停在左侧图片上，会出现圆形放大镜</p>
      <p>2. 移动鼠标可以查看图片不同区域的放大效果</p>
      <p>3. 使用上方的滑块可以调整放大倍数和放大镜尺寸</p>
    </div>
  </div>
</template>

<script>
import { ref, computed, onMounted } from 'vue'

export default {
  name: 'ImageMagnifier',
  props: {
    imageUrl: {
      type: String,
      required: true
    },
    initialZoom: {
      type: Number,
      default: 2
    },
    initialLensSize: {
      type: Number,
      default: 150
    }
  },
  setup(props) {
    // 响应式数据
    const zoomLevel = ref(props.initialZoom)
    const lensSize = ref(props.initialLensSize)
    const mouseX = ref(0)
    const mouseY = ref(0)
    const isMagnifierVisible = ref(false)
    const imageContainer = ref(null)
    const containerWidth = ref(500)
    const containerHeight = ref(350)

    // 计算放大镜位置样式
    const lensStyle = computed(() => {
      if (!isMagnifierVisible.value) return {}
      
      const halfSize = lensSize.value / 2
      let x = mouseX.value - halfSize
      let y = mouseY.value - halfSize
      
      // 限制放大镜不超出图片边界
      const maxX = containerWidth.value - lensSize.value
      const maxY = containerHeight.value - lensSize.value
      
      x = Math.max(0, Math.min(x, maxX))
      y = Math.max(0, Math.min(y, maxY))
      
      return {
        width: `${lensSize.value}px`,
        height: `${lensSize.value}px`,
        left: `${x}px`,
        top: `${y}px`,
        opacity: 1
      }
    })

    // 计算放大图片的位置样式
    const magnifiedImageStyle = computed(() => {
      if (!isMagnifierVisible.value) return {}
      
      return {
        width: `${containerWidth.value * zoomLevel.value}px`,
        height: `${containerHeight.value * zoomLevel.value}px`,
        left: `-${(mouseX.value * zoomLevel.value) - (lensSize.value / 2)}px`,
        top: `-${(mouseY.value * zoomLevel.value) - (lensSize.value / 2)}px`
      }
    })

    // 处理鼠标移动
    const handleMouseMove = (event) => {
      const rect = event.target.getBoundingClientRect()
      mouseX.value = event.clientX - rect.left
      mouseY.value = event.clientY - rect.top
    }

    // 显示放大镜
    const showMagnifier = () => {
      isMagnifierVisible.value = true
    }

    // 隐藏放大镜
    const hideMagnifier = () => {
      isMagnifierVisible.value = false
    }

    // 组件挂载后获取容器尺寸
    onMounted(() => {
      if (imageContainer.value) {
        containerWidth.value = imageContainer.value.offsetWidth
        containerHeight.value = imageContainer.value.offsetHeight
      }
    })

    return {
      zoomLevel,
      lensSize,
      mouseX,
      mouseY,
      isMagnifierVisible,
      imageContainer,
      lensStyle,
      magnifiedImageStyle,
      handleMouseMove,
      showMagnifier,
      hideMagnifier
    }
  }
}
</script>

<style scoped>
.image-magnifier {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.image-magnifier-content {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 30px;
  margin-top: 30px;
}

.image-container {
  position: relative;
  width: 500px;
  height: 350px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
  cursor: none;
  transition: transform 0.3s ease;
}

.image-container:hover {
  transform: translateY(-5px);
}

.original-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.magnifier-lens {
  position: absolute;
  width: 150px;
  height: 150px;
  border: 2px solid rgba(255, 255, 255, 0.8);
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.2);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s;
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
  z-index: 10;
}

.magnifier-container {
  width: 400px;
  height: 400px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
  opacity: 0;
  transition: opacity 0.3s ease;
  position: relative;
}

.magnifier-image {
  position: absolute;
  max-width: none;
  transform-origin: 0 0;
}

.controls {
  background: white;
  padding: 20px;
  border-radius: 12px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  margin-top: 30px;
  max-width: 500px;
  width: 100%;
}

.control-group {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

label {
  font-weight: 600;
  color: #2c3e50;
}

input[type="range"] {
  width: 70%;
}

.instructions {
  margin-top: 30px;
  background: white;
  padding: 20px;
  border-radius: 12px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  max-width: 500px;
  width: 100%;
}

.instructions h3 {
  color: #2c3e50;
  margin-bottom: 10px;
}

.instructions p {
  color: #7f8c8d;
  line-height: 1.6;
}

.active {
  opacity: 1 !important;
}
</style>